﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Util
{/// <summary>
 /// 基目录操作（WebAPI时我会用到）
 /// </summary>
    public static class FileOperate
    {
        #region 获取指定目录或目录下文件的基路径
        /// <summary>
        /// 获取制定目录或目录下文件的基路径
        /// </summary>
        /// <param name="folder"></param>
        /// <param name="file"></param>
        /// <returns></returns>
        public static string GetPath(string folder, string file = "")
        {
            string path;
            if (string.IsNullOrEmpty(file))
            {
                path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, folder);
            }
            else
            {
                path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, folder + "\\" + file);
            }
            return path;
        }
        #endregion

        #region 验证路径是否为文件，否则为目录
        /// <summary>
        /// 验证路径是否为文件，否则为目录
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public static bool IsFile(string filePath)
        {
            return !string.IsNullOrEmpty(Path.GetExtension(filePath));
        }
        #endregion

        #region 检测指定文件是否存在
        /// <summary>
        /// 检测指定文件/目录是否存在,如果存在则返回true。
        /// </summary>
        /// <param name="filePath">绝对路径</param>
        /// <returns></returns>   
        public static bool IsExistFile(string filePath)
        {
            if (IsFile(filePath))
            {
                return File.Exists(filePath);
            }
            else
            {
                return Directory.Exists(filePath);
            }
        }
        #endregion

        #region 创建一个文件/目录
        /// <summary>
        /// 创建一个文件/目录。
        /// </summary>
        /// <param name="filePath">文件的绝对路径</param>
        public static void CreateFile(string folder, string file = "")
        {
            try
            {
                string path = GetPath(folder);
                if (!IsExistFile(path))
                {
                    Directory.CreateDirectory(path);
                }
                if (!string.IsNullOrEmpty(file))
                {
                    string paths = GetPath(folder, file);
                    if (!IsExistFile(paths))
                    {
                        //创建一个FileInfo对象
                        FileInfo files = new(paths);
                        //创建文件
                        FileStream fs = files.Create();
                        //关闭文件流
                        fs.Close();
                    }
                }
            }
            catch (Exception)
            {
                throw;
            }
        }
        #endregion

        #region 获取文件名(包含扩展名)
        /// <summary>
        /// 从文件的绝对路径中获取文件名( 包含扩展名 )
        /// </summary>
        /// <param name="filePath">文件的绝对路径</param>        
        public static string GetFileName(string filePath)
        {
            //获取文件的名称
            FileInfo fi = new(filePath);
            return fi.Name;
        }
        #endregion

        #region 获取文件名(不包含扩展名)
        /// <summary>
        /// 从文件的绝对路径中获取文件名( 不包含扩展名 )
        /// </summary>
        /// <param name="filePath">文件的绝对路径</param>        
        public static string GetFileNameNoExtension(string filePath)
        {
            //获取文件的名称
            FileInfo fi = new(filePath);
            return fi.Name.Split('.')[0];
        }
        #endregion

        #region 从文件的绝对路径中获取扩展名
        /// <summary>
        /// 从文件的绝对路径中获取扩展名
        /// </summary>
        /// <param name="filePath">文件的绝对路径</param>        
        public static string GetExtension(string filePath)
        {
            //获取文件的名称
            FileInfo fi = new(filePath);
            return fi.Extension;
        }
        #endregion

        #region 获取指定目录中的文件列表
        /// <summary>
        /// 获取指定目录中所有文件列表
        /// </summary>
        /// <param name="filePath">绝对路径</param>        
        public static string[] GetFileNames(string filePath)
        {
            //如果目录不存在，则抛出异常
            if (!IsExistFile(filePath))
            {
                throw new FileNotFoundException();
            }
            //获取文件列表
            return Directory.GetFiles(filePath);
        }
        #endregion

        #region 获取指定目录中所有子目录列表,若要搜索嵌套的子目录列表,请使用重载方法.
        /// <summary>
        /// 获取指定目录中所有子目录列表,若要搜索嵌套的子目录列表,请使用重载方法.
        /// </summary>
        /// <param name="filePath">目录名称</param>        
        public static string[] GetDirectories(string filePath)
        {
            //如果目录不存在，则抛出异常
            if (!IsExistFile(filePath))
            {
                throw new FileNotFoundException();
            }
            return Directory.GetDirectories(filePath);
        }
        #endregion

        #region 检测指定目录是否为空
        /// <summary>
        /// 检测指定目录是否为空
        /// </summary>
        /// <param name="filePath">目录名称</param>     
        public static bool IsEmptyDirectory(string filePath)
        {
            try
            {
                //判断是否存在文件
                string[] fileNames = GetFileNames(filePath);
                if (fileNames.Length > 0)
                {
                    return false;
                }
                //判断是否存在文件夹
                string[] directoryNames = GetDirectories(filePath);
                if (directoryNames.Length > 0)
                {
                    return false;
                }
                return true;
            }
            catch
            {
                return true;
            }
        }
        #endregion

        #region 获取指定目录及子目录中所有文件列表
        /// <summary>
        /// 获取指定目录及子目录中所有文件列表
        /// </summary>
        /// <param name="directoryPath">目录名称</param>
        /// <param name="searchPattern">模式字符串，"*"代表0或N个字符，"?"代表1个字符。
        /// 范例："Log*.xml"表示搜索所有以Log开头的Xml文件。</param>
        /// <param name="isSearchChild">是否搜索子目录</param>
        public static string[] GetFileNames(string directoryPath, string searchPattern, bool isSearchChild)
        {
            try
            {
                if (isSearchChild)
                {
                    return Directory.GetFiles(directoryPath, searchPattern, SearchOption.AllDirectories);
                }
                else
                {
                    return Directory.GetFiles(directoryPath, searchPattern, SearchOption.TopDirectoryOnly);
                }
            }
            catch (IOException ex)
            {
                throw ex;
            }
        }
        #endregion

        #region 检测指定目录中是否存在指定的文件
        /// <summary>
        /// 检测指定目录中是否存在指定的文件,若要搜索子目录请使用重载方法.
        /// </summary>
        /// <param name="filePath">指定目录的绝对路径</param>
        /// <param name="searchPattern">模式字符串，"*"代表0或N个字符，"?"代表1个字符。
        /// 范例："Log*.xml"表示搜索所有以Log开头的Xml文件。</param>        
        public static bool Contains(string filePath, string searchPattern)
        {
            try
            {
                //获取指定的文件列表
                string[] fileNames = GetFileNames(filePath, searchPattern, false);

                //判断指定文件是否存在
                if (fileNames.Length == 0)
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        #endregion

        #region 根据时间得到目录名 / 格式:yyyyMMdd 或者 HHmmssff

        /// <summary>
        /// 根据时间得到目录名yyyyMMdd
        /// </summary>
        /// <returns></returns>
        public static string GetDateDir()
        {
            return DateTime.Now.ToString("yyyyMMdd");
        }
        /// <summary>
        /// 根据时间得到文件名HHmmssff
        /// </summary>
        /// <returns></returns>
        public static string GetDateFile()
        {
            return DateTime.Now.ToString("HHmmssff");
        }
        #endregion

        #region 创建一个文件,并将字节流写入文件。
        /// <summary>
        /// 创建一个文件,并将字节流写入文件。
        /// </summary>
        /// <param name="filePath">文件的绝对路径</param>
        /// <param name="buffer">二进制流数据</param>
        public static void CreateFile(string folder, string file, byte[] buffer)
        {
            try
            {
                CreateFile(folder);
                string filePath = GetPath(folder, file);
                //如果文件不存在则创建该文件
                if (!IsExistFile(filePath))
                {
                    //创建一个FileInfo对象
                    FileInfo files = new(filePath);
                    //创建文件
                    FileStream fs = files.Create();
                    //写入二进制流
                    fs.Write(buffer, 0, buffer.Length);
                    //关闭文件流
                    fs.Close();
                }
            }
            catch (Exception)
            {
                throw;
            }
        }
        #endregion

        #region 获取一个文件的长度,单位为Byte
        /// <summary>
        /// 获取一个文件的长度,单位为Byte
        /// </summary>
        /// <param name="filePath">文件的绝对路径</param>        
        public static int GetFileSize(string folder, string file)
        {
            string filePath = GetPath(folder, file);
            if (IsExistFile(filePath))
            {
                //创建一个文件对象
                FileInfo fi = new(filePath);
                //获取文件的大小
                return (int)fi.Length;
            }
            else
            {
                throw new FileNotFoundException();
            }
        }
        #endregion

        #region 获取指定目录中的子目录列表
        /// <summary>
        /// 获取指定目录及子目录中所有子目录列表
        /// </summary>
        /// <param name="directoryPath">指定目录的绝对路径</param>
        /// <param name="searchPattern">模式字符串，"*"代表0或N个字符，"?"代表1个字符。
        /// 范例："Log*.xml"表示搜索所有以Log开头的Xml文件。</param>
        /// <param name="isSearchChild">是否搜索子目录</param>
        public static string[] GetDirectories(string directoryPath, string searchPattern, bool isSearchChild)
        {
            try
            {
                //如果目录不存在，则抛出异常
                if (!IsExistFile(directoryPath))
                {
                    throw new DirectoryNotFoundException();
                }
                if (isSearchChild)
                {
                    return Directory.GetDirectories(directoryPath, searchPattern, SearchOption.AllDirectories);
                }
                else
                {
                    return Directory.GetDirectories(directoryPath, searchPattern, SearchOption.TopDirectoryOnly);
                }
            }
            catch (IOException ex)
            {
                throw ex;
            }
        }
        #endregion

        #region 将现有文件的内容复制到新文件中
        /// <summary>
        /// 将源文件的内容复制到目标文件中
        /// </summary>
        /// <param name="sourceFilePath">源文件的绝对路径</param>
        /// <param name="destFilePath">目标文件的绝对路径</param>
        public static void Copy(string sourceFilePath, string destFilePath)
        {
            File.Copy(sourceFilePath, destFilePath, true);
        }
        #endregion

        #region 将文件移动到指定目录
        /// <summary>
        /// 将文件移动到指定目录
        /// </summary>
        /// <param name="sourceFilePath">需要移动的源文件的绝对路径</param>
        /// <param name="descDirectoryPath">移动到的目录的绝对路径</param>
        public static void Move(string sourceFilePath, string descDirectoryPath)
        {
            //获取源文件的名称
            string sourceFileName = GetFileName(sourceFilePath);

            if (IsExistFile(descDirectoryPath))
            {
                //如果目标中存在同名文件,则删除
                if (IsExistFile(descDirectoryPath + "\\" + sourceFileName))
                {
                    DeleteFile(descDirectoryPath + "\\" + sourceFileName);
                }
                //将文件移动到指定目录
                File.Move(sourceFilePath, descDirectoryPath + "\\" + sourceFileName);
            }
        }
        #endregion

        #region 清空指定目录
        /// <summary>
        /// 清空指定目录下所有文件及子目录,但该目录依然保存.
        /// </summary>
        /// <param name="directoryPath">指定目录的绝对路径</param>
        public static void ClearDirectory(string directoryPath)
        {
            if (IsExistFile(directoryPath))
            {
                //删除目录中所有的文件
                string[] fileNames = GetFileNames(directoryPath);
                for (int i = 0; i < fileNames.Length; i++)
                {
                    DeleteFile(fileNames[i]);
                }

                //删除目录中所有的子目录
                string[] directoryNames = GetDirectories(directoryPath);
                for (int i = 0; i < directoryNames.Length; i++)
                {
                    DeleteFile(directoryNames[i]);
                }
            }
        }
        #endregion

        #region 清空文件内容
        /// <summary>
        /// 清空文件内容
        /// </summary>
        /// <param name="filePath">文件的绝对路径</param>
        public static void ClearFile(string folder, string file)
        {
            DeleteFile(GetPath(folder, file));
            //重新创建该文件
            CreateFile(folder, file);
        }
        #endregion

        #region 删除指定目录/文件
        /// <summary>
        /// 删除指定目录及其所有子目录
        /// </summary>
        /// <param name="directoryPath">指定目录的绝对路径</param>
        public static void DeleteFile(string fileFullPath)
        {
            if (IsExistFile(fileFullPath))
            {
                if (IsFile(fileFullPath))
                {
                    // 3.2、删除文件
                    File.Delete(fileFullPath);
                }
                else
                {
                    // 3.1、删除文件夹
                    Directory.Delete(fileFullPath, true);
                }
            }
        }
        #endregion
    }
}
